package com.kadron.servlets;

import java.io.Serializable;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.UserTransaction;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.transaction.Transaction;

import com.kadron.common.KConst;
import com.kadron.common.KUtil;
import com.kadron.common.PasswordUtil;
import com.kadron.dao.KConfirmKeyDAO;
import com.kadron.entity.ConfirmKey;
import com.kadron.entity.User;
import com.kadron.enumeration.UserStatus;
import com.kadron.exceptions.KPersistenceException;
import com.kadron.manager.KMessageManager;
import com.kadron.service.UserHistoryService;
import com.kadron.transaction.KTx;

@AutoCreate
@Scope(ScopeType.PAGE)
@Name("userConfirmation")
public class UserConfirmation extends KMessageManager implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -7391368085322295543L;

	private String message;
	private String password;
	private String confirmPassword;
	private ConfirmKey confirmKey;
	private User user;
	private boolean confirmAvb = true;
	
	@In
	private KConfirmKeyDAO confirmKeyDAO;
	@In
    private UserHistoryService userHistoryService;
	
	@Create
	public void init() {
		HttpServletRequest req = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
		HttpServletResponse resp = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
		String key = req.getParameter("key");
		String pid = req.getParameter("pid");
		if (KUtil.isEmpty(key) || KUtil.isEmpty(pid)) {
			message = "confirmation_key_not_correct";
			confirmAvb = false;
			return;
		}
		try {
			Long userId = Long.valueOf(pid);
			ConfirmKey confirmKey = confirmKeyDAO.getUserKadrons(key, userId);
			if (confirmKey == null) {
				resp.sendRedirect(req.getContextPath());
				FacesContext.getCurrentInstance().responseComplete();
				return;		
			}
			User user = confirmKeyDAO.find(confirmKey.getUser().getId(), User.class);
			if (!UserStatus.SIGNED_UP.equals(user.getUserStatus())) {
				message = "already_confirmed";				
				confirmAvb = false;
				return;
			}
			this.user = user;
			this.confirmKey = confirmKey;
		} catch (Exception e) {
			e.printStackTrace();
			confirmAvb = false;
			setError(true);
			message = "confirmation_key_not_correct";
		}
	}

	public void changePassword() {
		String criptedPassword = PasswordUtil.cript(password);
		if (KUtil.isEmpty(password) 
				|| KUtil.isEmpty(confirmPassword) 
				|| criptedPassword.equals(user.getPassword())
				|| !password.equals(confirmPassword)) {
			bad("field_values_are_not_correct");
			return;
		}
		UserTransaction tx = null;
		try {
			synchronized (user) {				
				tx = Transaction.instance();
				user.setPassword(criptedPassword);
				user.setUserStatus(UserStatus.REGISTERED);
				user.setRegDate(KUtil.getMoment()); //Remember time of confirming registration
				user = (User) confirmKeyDAO.update(user);
				userHistoryService.create(user, "USER_CONFIRMATION", "USER_CONFIRMATION", "User confirmed security key and it is REGISTERED");
				confirmKey.setConfirmed(true);
				confirmKeyDAO.update(confirmKey);
				tx.commit();
			}
			message = "success_registration";
			confirmAvb = false;
			good();
		} catch (KPersistenceException e) {
			KTx.rollback(tx);
			KTx.begin(tx);
			bad(KConst.VERSION_CHANGED);
		} catch (Exception e) {
			e.printStackTrace();
			bad(KConst.BAD_THING);
			KTx.rollback(tx);
			KTx.begin(tx);
		}
	}
	
	public String getMessage() {
		return message;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getConfirmPassword() {
		return confirmPassword;
	}

	public void setConfirmPassword(String confirmPassword) {
		this.confirmPassword = confirmPassword;
	}

	public boolean isConfirmAvb() {
		return confirmAvb;
	}
}
